package org.llc.authorization.config.extend;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.llc.authorization.config.util.AuthProperties;
import org.springframework.context.annotation.Primary;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
import org.springframework.stereotype.Component;
import org.llc.authorization.service.UserAccountService;
import org.llc.common.starter.constants.Oauth2ExceptionEnum;
import org.llc.common.starter.model.UserAccount;
import org.llc.common.starter.util.BpwdEncoderUtil;

import javax.annotation.Resource;

/**
 * 用户名密码授权类型鉴权
 *
 * @author llc
 * @date 2020/2/27 11:28
 * @since 1.0.0
 */
@Component
@Primary
@Slf4j
public class UsernamePasswordAuthenticator extends AbstractPrepareIntegrationAuthenticator {

    /**
     * 用户名密码授权类型
     */
    private final static String AUTH_TYPE = "password";

    /**
     * 用户账户Service
     */
    @Resource
    private UserAccountService userAccountService;

    /**
     * 根据用户名密码方式进行认证
     * @param entity 集成认证实体
     * @return org.llc.common.model.UserAccount
     * @author llc
     * @date 2020/2/27 14:46
     */
    @Override
    public UserAccount authenticate(IntegrationAuthenticationEntity entity) {

        // 获取用户名密码
        String username = entity.getAuthParameter(AuthProperties.USERNAME_PARAMETER_NAME);
        String password = entity.getAuthParameter(AuthProperties.PASSWORD_PARAMETER_NAME);

        // 用户名或密码为空
        if(StringUtils.isBlank(username) || StringUtils.isBlank(password)){
            throw new OAuth2Exception(Oauth2ExceptionEnum.USERNAME_OR_PASSWORD_NULL.getMsg());
        }
        // 根据用户名或手机号查询用户账户
        UserAccount userAccount = userAccountService.selectByUserName(username);
        if(null == userAccount){
            throw new OAuth2Exception(Oauth2ExceptionEnum.USER_NOT_FOUND.getMsg());
        }
        // 验证密码正确性
        if(!BpwdEncoderUtil.matches(password,userAccount.getPassword())){
            throw new OAuth2Exception(Oauth2ExceptionEnum.PASSWORD_ERR.getMsg());
        }
        // 验证用户可用性
        userAccountService.validateUser(userAccount);

        // 组合用户账户对象与角色权限
        return userAccountService.composeUserAccountAndAuthority(userAccount);
    }

    /**
     * 认证类型为空时为用户名密码方式
     * {@inheritDoc}
     * @author llc
     * @date 2020/2/27 12:21
     */
    @Override
    public boolean support(IntegrationAuthenticationEntity entity) {
        // 认证类型
        String authType = entity.getAuthType();
        return StringUtils.isEmpty(authType) || authType.equals(AUTH_TYPE);
    }

}
